<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :title="title"
    :width="1200"
    :maskClosable="false"
    :defaultFullscreen="true"
    :confirmLoading="confirmLoading"
    @ok="handleSubmit"
  >
    <template #default>
      <BasicForm ref="formRef" @register="registerForm">
        <template #analyseButton="{ values }">
          <div style="flex: 1; text-align: right">
            <a-popover v-if="values.dataType == 'sql'" title="使用指南" trigger="hover" style="margin: 0 10px 0 6px" }>
              <template #content>
                您可以键入“”作为一个参数，这里abc是参数的名称。例如： <br />
                select * from table where id = ${abc}。 <br />
                select * from table where id like concat('%',${abc},'%')。(mysql模糊查询) <br />
                select * from table where id like '%'||${abc}||'%'。(oracle模糊查询)<br />
                select * from table where id like '%'+${abc}+'%'。(sqlserver模糊查询)<br />
              </template>
              <template #default>
                <a-icon type="question-circle" />
              </template>
            </a-popover>
            <a-button v-if="values.dataType == 'api'" style="margin-left: 10px" type="primary" @click="handleFieldAnalyze">API解析</a-button>
            <a-button v-if="values.dataType == 'json'" style="margin-left: 10px" type="primary" @click="handleFieldAnalyze">JSON解析</a-button>
            <a-button v-if="values.dataType == 'sql'" style="margin-left: 10px" type="primary" @click="handleSQLAnalyze">SQL解析</a-button>
          </div>
        </template>
      </BasicForm>
      <a-divider style="margin: 1px 0" class="cust-divider" />
      <a-tabs @change="handleChangeTabs" :animated="false" v-model:activeKey="activeKey">
        <a-tab-pane tab="列表字段" :key="refKeys[0]" forceRender>
          <JVxeTable
            ref="onlGraphreportItem"
            toolbar
            row-number
            row-selection
            keep-source
            dragSort
            :height="390"
            :loading="onlGraphreportItemTable.loading"
            :dataSource="onlGraphreportItemTable.dataSource"
            :columns="onlGraphreportItemTable.columns"
          >
            <template #toolbarSuffix>
              <Dropdown>
                <a-button preIcon="ant-design:down" :ant-click-animating-without-extra-node="false">转换字段名</a-button>

                <template #overlay>
                  <Menu @click="handleMenuClick">
                    <MenuItem key="toUpper" text="转换为大写" icon="ant-design:sort-descending-outlined" />
                    <MenuItem key="toLower" text="转换为小写" icon="ant-design:sort-ascending-outlined" />
                    <!-- <MenuDivider  /> -->
                  </Menu>
                </template>
              </Dropdown>
            </template>
          </JVxeTable>
        </a-tab-pane>
        <a-tab-pane tab="图表参数" :key="refKeys[1]" forceRender>
          <a-alert type="info" show-icon class="alert">
            <template #message>
              <span>目前只有SQL模式才支持报表参数！</span>
            </template>
          </a-alert>
          <JVxeTable
            ref="onlGraphreportParam"
            toolbar
            row-number
            row-selection
            keep-source
            dragSort
            :height="390"
            :loading="onlGraphreportParamTable.loading"
            :dataSource="onlGraphreportParamTable.dataSource"
            :columns="onlGraphreportParamTable.columns"
          />
        </a-tab-pane>
      </a-tabs>
    </template>
  </BasicModal>
</template>
<script lang="ts">
  import { defineComponent, ref, reactive, unref, computed } from 'vue';
  import { useModalInner, BasicModal } from '/@/components/Modal';
  import { useForm, BasicForm } from '/@/components/Form/index';
  import { JVxeTable } from '/@/components/jeecg/JVxeTable';
  import { useJvxeMethod } from '/@/hooks/system/useJvxeMethods';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { Alert } from 'ant-design-vue';
  import { Dropdown, Menu } from 'ant-design-vue';
  import { onlGraphreportParamList, onlGraphreportItemList, saveOrUpdate, analyzeSql, analyzeField } from '../graphreport.api';
  import { formSchema, graphreportParamColumns, graphreportItemColumns } from '../graphreport.data';
  import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';

  export default defineComponent({
    name: 'GraphreportModal',
    components: {
      BasicModal,
      BasicForm,
      JVxeTable,
      Alert,
      Dropdown,
      Menu,
      MenuItem: createAsyncComponent(() => import('../components/DropMenuItem.vue')),
      MenuDivider: Menu.Divider,
    },
    props: {},
    emits: ['register', 'success'],
    setup(props, { emit }) {
      const { createMessage } = useMessage();
      const isUpdate = ref(true);
      const confirmLoading = ref(true);
      const refKeys = ref(['onlGraphreportItem', 'onlGraphreportParam']);
      const activeKey = ref('onlGraphreportItem');
      const onlGraphreportParam = ref();
      const onlGraphreportItem = ref();
      const tableRefs = { onlGraphreportItem, onlGraphreportParam };
      const onlGraphreportParamTable = reactive({
        loading: false,
        dataSource: [],
        columns: graphreportParamColumns,
      });
      const onlGraphreportItemTable = reactive({
        loading: false,
        dataSource: [],
        columns: graphreportItemColumns,
      });
      const [registerForm, { setProps, resetFields, setFieldsValue, validateFields, updateSchema }] = useForm({
        schemas: formSchema,
        showActionButtonGroup: false,
      });
      const [handleChangeTabs, handleSubmit, requestSubTableData, formRef] = useJvxeMethod(
        requestAddOrEdit,
        classifyIntoFormData,
        tableRefs,
        activeKey,
        refKeys
      );
      const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
        var _a, _b;
        await reset();
        setModalProps({
          confirmLoading: false,
          showCancelBtn: data == null ? void 0 : data.showFooter,
          showOkBtn: data == null ? void 0 : data.showFooter,
        });
        isUpdate.value = !!(data == null ? void 0 : data.isUpdate);
        if (unref(isUpdate)) {
          await setFieldsValue(Object.assign({}, data.record));
          let params = { headId: (_a = data == null ? void 0 : data.record) == null ? void 0 : _a.id };
          requestSubTableData(onlGraphreportParamList, params, onlGraphreportParamTable);
          params = { headId: (_b = data == null ? void 0 : data.record) == null ? void 0 : _b.id };
          requestSubTableData(onlGraphreportItemList, params, onlGraphreportItemTable);
        }
        setProps({ disabled: !(data == null ? void 0 : data.showFooter) });
      });
      const title = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
      async function reset() {
        await resetFields();
        activeKey.value = 'onlGraphreportItem';
        onlGraphreportParamTable.dataSource = [];
        onlGraphreportItemTable.dataSource = [];
      }
      function classifyIntoFormData(allValues) {
        let main = Object.assign({}, allValues.formValue);
        return {
          ...main, // 展开
          onlGraphreportItemList: allValues.tablesValue[0].tableData,
          onlGraphreportParamList: allValues.tablesValue[1].tableData,
        };
      }
      async function requestAddOrEdit(values) {
        try {
          setModalProps({ confirmLoading: true });
          let params = [],
            items = [],
            head = {};
          Object.keys(values).map((k) => {
            if (k == 'onlGraphreportItemList') {
              items = values[k];
            } else if (k == 'onlGraphreportParamList') {
              params = values[k];
            } else {
              head[k] = values[k];
            }
          });
          let obj = { ...head, diagramItemList: items, diagramParamList: params };
          console.log('报表配置保存请求参数', obj);
          await saveOrUpdate(obj, isUpdate.value);
          closeModal();
          emit('success');
        } finally {
          setModalProps({ confirmLoading: false });
        }
      }
      function handleSQLAnalyze() {
        setModalProps({ confirmLoading: true });
        validateFields(['cgrSql', 'dbSource'])
          .then((values) => {
            let { cgrSql, dbSource } = values;
            let urlParam = 'sql=' + encodeURIComponent(cgrSql);
            if (dbSource) {
              urlParam += '&dbKey=' + dbSource;
            }
            analyzeSql(urlParam).then((res) => {
              if (res) {
                createMessage.success('解析成功');
                let { fields, params } = res;
                let newFields = fields.filter((item) => item.fieldName != '__row_number__');
                let itemDataSource = onlGraphreportItem.value.getTableData();
                let newItemDataList = getTabData(itemDataSource, newFields || [], 'fieldName');
                newItemDataList = newItemDataList.sort((a, b) => a.orderNum - b.orderNum);
                onlGraphreportItemTable.dataSource = newItemDataList;
                let paramDataSource = onlGraphreportParam.value.getTableData();
                let newParamList = getTabData(paramDataSource, params || [], 'paramName');
                newParamList = newParamList.sort((a, b) => a.orderNum - b.orderNum);
                onlGraphreportParamTable.dataSource = newParamList;
              }
            });
          })
          .catch(() => {
            console.log('解析失败');
          })
          .finally(() => {
            setModalProps({ confirmLoading: false });
          });
      }

      function handleFieldAnalyze() {
        setModalProps({ confirmLoading: true });
        validateFields(['cgrSql', 'dataType'])
          .then((values) => {
            let { cgrSql, dataType } = values;
            let params = {
              data: cgrSql,
              type: dataType,
            };
            analyzeField(params).then((res) => {
              if (res) {
                createMessage.success('解析成功');
                let fields = res;
                let itemDataSource = onlGraphreportItem.value.getTableData();
                let newItemDataList = getTabData(itemDataSource, fields || [], 'fieldName');
                newItemDataList = newItemDataList.sort((a, b) => a.orderNum - b.orderNum);
                onlGraphreportItemTable.dataSource = newItemDataList;
                let paramDataSource = onlGraphreportParam.value.getTableData();
                let newParamList = getTabData(paramDataSource, [], 'paramName');
                newParamList = newParamList.sort((a, b) => a.orderNum - b.orderNum);
                onlGraphreportParamTable.dataSource = newParamList;
              }
            });
          })
          .catch(() => {
            console.log('解析失败');
          })
          .finally(() => {
            setModalProps({ confirmLoading: false });
          });
      }

      function getTabData(old_arr, new_arr, columnName) {
        if (old_arr.length > 0) {
          let need = [],
            field_arr = [],
            max_order = 1;
          for (let t of new_arr) {
            for (let o of old_arr) {
              if (o[columnName] == t[columnName]) {
                need.push(o);
                field_arr.push(t[columnName]);
                if (o.orderNum > max_order) {
                  max_order = o.orderNum;
                }
                break;
              }
            }
          }
          for (let t of new_arr) {
            if (field_arr.indexOf(t[columnName]) < 0) {
              t.orderNum = ++max_order;
              need.push(t);
            }
          }
          return need;
        } else {
          let max_order = 0;
          for (let t of new_arr) {
            if (!t.orderNum) {
              t.orderNum = ++max_order;
            }
          }
          return new_arr;
        }
      }
      function handleMenuClick(e: { key: MenuEvent }) {
        switch (e.key) {
          case 'toUpper':
            handleToUpper();
            break;
          case 'toLower':
            handleToLower();
            break;
        }
      }

      function handleToUpper() {
        let itemDataList = onlGraphreportItem.value.getTableData();
        if (itemDataList && itemDataList.length > 0) {
          for (let item of itemDataList) {
            item.fieldName = item.fieldName?.toUpperCase();
          }
        }
        onlGraphreportItemTable.dataSource = itemDataList;
      }

      function handleToLower() {
        let itemDataList = onlGraphreportItem.value.getTableData();
        if (itemDataList && itemDataList.length > 0) {
          for (let item of itemDataList) {
            item.fieldName = item.fieldName?.toLowerCase();
          }
        }
        onlGraphreportItemTable.dataSource = itemDataList;
      }

      return {
        formRef,
        activeKey,
        title,
        refKeys,
        confirmLoading,
        onlGraphreportParam,
        onlGraphreportItem,
        onlGraphreportItemTable,
        onlGraphreportParamTable,
        registerModal,
        registerForm,
        handleChangeTabs,
        handleSubmit,
        handleSQLAnalyze,
        handleFieldAnalyze,
        handleMenuClick,
      };
    },
  });
</script>
<style scoped></style>
